package com.frontend.authservice.service.Impl.security;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.frontend.authservice.Entity.OauthClientDetails;
import com.frontend.authservice.mapper.OauthClientDetailsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

@Service

public class CustomClientDetailsService  implements ClientDetailsService {
    @Resource
    private OauthClientDetailsMapper oauthClientDetailsMapper;
    @Autowired
    private PasswordEncoder passwordEncoder; // 注入密码编码器用于测试
    public void testPasswordEncoding() {
        String rawPassword = "gateway-secret";
        String encodedPassword = passwordEncoder.encode(rawPassword);
        boolean matches = passwordEncoder.matches(rawPassword, encodedPassword);
        System.out.println("Raw password: " + rawPassword);
        System.out.println("Encoded password: " + encodedPassword);
        System.out.println("Matches: " + matches);
    }
    @Override
    public ClientDetails loadClientByClientId(String s) throws ClientRegistrationException {
        QueryWrapper<OauthClientDetails> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("client_id",s)
                .eq("enabled",1);
        OauthClientDetails oauthClientDetails1 = oauthClientDetailsMapper.selectOne(queryWrapper);
        // 转换为 Spring Security OAuth2 需要的 ClientDetails 对象
        BaseClientDetails clientDetails = new BaseClientDetails();
        //这个的意思是网关要带着gateway-client和gateway-secret才能访问
        // 网关客户端ID
        clientDetails.setClientId(oauthClientDetails1.getClientId());
        // 网关客户端密钥
        clientDetails.setClientSecret(oauthClientDetails1.getClientSecret());
        // 添加测试方法（仅用于测试）



        // 设置授权范围
        if (oauthClientDetails1.getScope() != null && !oauthClientDetails1.getScope().isEmpty()) {
            //代表着当前认证的_token 只能read: 读取权限 - 可以查看、获取数据
            //代表着当前认证的_token 只能write: 写入权限 - 可以创建、修改、删除数据
            List<String> list = Arrays.asList(oauthClientDetails1.getScope().split(","));
            clientDetails.setScope(Arrays.asList(oauthClientDetails1.getScope().split(",")));
        }
        System.out.println("设置的scope: " + clientDetails.getScope());
        // 设置授权类型
        if (oauthClientDetails1.getAuthorizedGrantTypes() != null && !oauthClientDetails1.getAuthorizedGrantTypes().isEmpty()) {
            //password - 密码模式：
            //网关可以使用用户的用户名和密码来获取访问令牌
            //适用于用户直接登录的场景
            //refresh_token - 刷新令牌模式当访问令牌过期后，可以使用刷新令牌获取新的访问令牌无需用户重新输入密码(给令牌续时间)
            //client_credentials - 客户端凭证模式：
            //网关可以仅使用自己的身份（客户端ID和密码）获取令牌
            //适用于不需要用户身份的后台服务间调用


            clientDetails.setAuthorizedGrantTypes(Arrays.asList(oauthClientDetails1.getAuthorizedGrantTypes().split(",")));
        }
        System.out.println("设置的授权类型: " + clientDetails.getAuthorizedGrantTypes());

        // 设置访问令牌和刷新令牌有效期
        clientDetails.setAccessTokenValiditySeconds(oauthClientDetails1.getAccessTokenValidity());
        clientDetails.setRefreshTokenValiditySeconds(oauthClientDetails1.getRefreshTokenValidity());
        System.out.println("令牌有效期: " + oauthClientDetails1.getAccessTokenValidity() + "秒");

        // 设置资源ID
        if (clientDetails.getResourceIds() != null && !clientDetails.getResourceIds().isEmpty()) {
            clientDetails.setResourceIds(Arrays.asList(oauthClientDetails1.getResourceIds().split(",")));
        }
        // 配置回调地址

        if (oauthClientDetails1.getWebServerRedirectUri() != null && !oauthClientDetails1.getWebServerRedirectUri().isEmpty()) {
            clientDetails.setRegisteredRedirectUri(
                    Set.of(oauthClientDetails1.getWebServerRedirectUri().split(","))
            );}
        System.out.println("回调地址: " + clientDetails.getRegisteredRedirectUri());

        System.out.println("客户端详情加载完成: " + clientDetails.getClientId());
        return clientDetails;
    }
}
